package com.lalilu.lread.ui.weight

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewGroup
import kotlin.math.min

class FloatMenu @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {

    private val maxColumn = 4
    private val horizontalSpacing = 55
    private val verticalSpacing = 20
    private val shadowColor = Color.parseColor("#FF444444")
    private val bgColor = Color.parseColor("#D4777777")
    private val bgRadius = 20f

    private val bgRectF = RectF()
    private val bgPaint = Paint().also {
        it.isAntiAlias = true
        it.color = bgColor
    }

    private var circleX = 0f
    private var circleY = 0f
    private var circleRadius = 0f
    private val circlePaint = Paint().also {
        it.isAntiAlias = true
        it.color = shadowColor
        it.alpha = 0
    }

    init {
        this.setBackgroundColor(Color.TRANSPARENT)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        return true
    }

    val reverseAnimator = ValueAnimator.ofFloat(1f, 0f).also {
        it.addUpdateListener { value ->
            val v = value.animatedValue as Float
            circleRadius = v * 200f
            circlePaint.alpha = ((1f - v) * 255).toInt()
            invalidate()
        }
    }

    val animator = ValueAnimator.ofFloat(0f, 1f).also {
        it.addUpdateListener { value ->
            val v = value.animatedValue as Float
            circleRadius = v * 200f
            circlePaint.alpha = ((1f - v) * 255).toInt()
            invalidate()
            if (v >= 1f) {
                reverseAnimator.start()
            }
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                circleX = ev.x
                circleY = ev.y
                invalidate()
                animator.start()
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    var widthMode = 0
    var heightMode = 0

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        widthMode = MeasureSpec.getMode(widthMeasureSpec)
        heightMode = MeasureSpec.getMode(heightMeasureSpec)
        val widthSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)

        var resultWidth = if (widthMode == MeasureSpec.EXACTLY) widthSize else -1
        var resultHeight = if (heightMode == MeasureSpec.EXACTLY) heightSize else -1

        var layoutWidth = 0             // 容器已经被占据的宽度
        var layoutHeight = 0            // 容器已经被占据的宽度
        var maxChildHeight = 0          // 最高的子元素高度
        var maxContainerWidth = 0       // 容器的最大宽度
        var maxRowCount = 1             // 最大行数
        val maxColumnCount = min(maxColumn, childCount) // 最大列数


        for (i in 0 until childCount) {
            val child = getChildAt(i)

            measureChild(child, widthMeasureSpec, heightMeasureSpec)
            val childWidth = child.measuredWidth
            val childHeight = child.measuredHeight

            // wrap_content 情况下 通过限制最大列数换行
            val isWrapContent = resultWidth == -1 && i != 0 && i % maxColumn == 0
            // match_parent 或者指定宽度情况下 通过获取到的可用宽度换行
            val isOverWidth =
                resultWidth != -1 && childWidth + layoutWidth > resultWidth - paddingStart - paddingEnd

            // 放不下就换行
            if (isWrapContent || isOverWidth) {
                layoutWidth = 0
                layoutHeight += maxChildHeight
                maxChildHeight = 0
                maxRowCount++
            }

            // 判断高度是否是这一行之中最高的
            if (childHeight > maxChildHeight) {
                maxChildHeight = childHeight
            }

            // 将该子元素的宽度累加进已占据的行宽中
            layoutWidth += childWidth
            if (layoutWidth > maxContainerWidth) {
                maxContainerWidth = layoutWidth
            }
        }

        if (widthMode != MeasureSpec.EXACTLY) {
            resultWidth = maxContainerWidth + paddingStart + paddingEnd
            resultWidth += horizontalSpacing * (maxColumnCount - 1)
        }
        if (heightMode != MeasureSpec.EXACTLY) {
            resultHeight = layoutHeight + maxChildHeight + paddingTop + paddingBottom
            resultHeight += verticalSpacing * (maxRowCount - 1)
        }

        setMeasuredDimension(resultWidth, resultHeight)

        // 背景位置
        bgRectF.set(0f, 0f, resultWidth.toFloat(), resultHeight.toFloat())
    }

    private val xFermode = PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)
    private val emptyPaint = Paint().also {
        it.isAntiAlias = true
        it.color = bgColor
    }

    override fun onDraw(canvas: Canvas) {
        // 绘制背景
        canvas.drawRoundRect(bgRectF, bgRadius, bgRadius, bgPaint)
        val saveCount = canvas.saveLayer(bgRectF, bgPaint)
        canvas.drawRoundRect(bgRectF, bgRadius, bgRadius, emptyPaint)

        circlePaint.xfermode = xFermode
        canvas.drawCircle(circleX, circleY, circleRadius, circlePaint)
        circlePaint.xfermode = null

        canvas.restoreToCount(saveCount)
        // 绘制波浪扩散圆圈
    }


    override fun onLayout(p0: Boolean, p1: Int, p2: Int, p3: Int, p4: Int) {
        var layoutWidth = 0 // 容器已经被占据的宽度
        var layoutHeight = 0 // 容器已经被占据的宽度
        var maxChildHeight = 0

        for (i in 0 until childCount) {
            val child = getChildAt(i)

            // 判断是否最高的元素
            if (child.measuredHeight > maxChildHeight) {
                maxChildHeight = child.measuredHeight
            }

            // 放不下就换行
            if (child.measuredWidth + layoutWidth > width - (paddingStart + paddingEnd)) {
                layoutWidth = 0
                layoutHeight += maxChildHeight
                if (heightMode != MeasureSpec.EXACTLY) {
                    layoutHeight += verticalSpacing
                }
                maxChildHeight = 0
            }

            if (widthMode != MeasureSpec.EXACTLY && i % maxColumn != 0) {
                layoutWidth += horizontalSpacing
            }
            // 为子元素定位
            child.layout(
                layoutWidth + paddingStart,
                layoutHeight + paddingTop,
                layoutWidth + child.measuredWidth + paddingStart,
                layoutHeight + child.measuredHeight + paddingTop
            )

            // 将该子元素的宽度累加进已占据的行宽中
            layoutWidth += child.measuredWidth
        }
    }
}